/**
 * 获取随机数的函数
 * @param {number} a 代表范围的数字
 * @param {number} b 代表范围的数字
 * @return {number} 返回范围内的随机整数
 */
function getRandom(a, b){
    return Math.floor(Math.random() * Math.abs(a - b)) + Math.min(a, b)
}
/**
 * 获取16进制的随机颜色值
 */
function getColor(){
    var color = '#'
    for(var i=0;i<3;i++){
        var hex = getRandom(0, 256).toString(16)
        color += hex.length === 1 ? '0' + hex : hex;
    }
    return color
}
/**
 * 批量设置样式的函数
 * @param {node} ele 被设置样式的标签对象
 * @param {object} styleObj 要设置的样式组成的键值对
 */
function setStyle(ele, styleObj){
    for(var key in styleObj){
        ele.style[key] = styleObj[key]
    }
}
/**
 * 进行动画的函数
 * @param {node} ele 要进行动画的元素
 * @param {object} obj 动画的属性和值组成的键值对
 * @param {function} fn 动画结束后要执行的函数
 */
function animate(ele, obj, fn){ 
    var k = 0
    for(var key in obj){
        k++
        (function(key){
            var currentStyle = getComputedStyle(ele)[key]
            var target = obj[key]
            if(key === 'opacity'){
                currentStyle *= 100
                target *= 100
            }
            currentStyle = parseInt(currentStyle)
            var timerId = setInterval(function(){
                var speed = (target - currentStyle) / 20
                currentStyle += speed > 0 ? Math.ceil(speed) : Math.floor(speed)
                if(key === 'opacity') ele.style[key] = currentStyle / 100
                else ele.style[key] = currentStyle + 'px'
                if(currentStyle === target){
                    clearInterval(timerId)
                    if(--k === 0) fn()
                }
            }, 20)
        })(key)
    }
}
/**
 * 获取cookie的函数
 * @param {string} key 要获取的cookie的键
 * @returns key对应的值
 */
function getCookie(key){
    var cookie = document.cookie;
    var arr = cookie.split('; ')
    for(var i=0;i<arr.length;i++){
        var brr = arr[i].split('=')
        if(brr[0] === key){
            return brr[1]
        }
    }
}
/**
 * 设置cookie的函数
 * @param {string} key 要设置的cookie的键
 * @param {string} value key对应的值
 * @param {number} seconds 有效的秒
 */
function setCookie(key, value, seconds){
    var date = new Date()
    date.setTime(date.getTime()+seconds*1000-8*3600*1000)
    document.cookie = key + '='+value+';expires='+date
}
/**
 * 删除cookie的函数
 * @param {string} key 要删除的cookie的键
 */
function removeCookie(key){
    setCookie(key, null, -1)
}
/**
 * 发送ajax请求的函数
 * @param {object} obj 发送ajax的配置项
 * @returns undefined
 */
function ajax(obj){
    if(obj.url === undefined) throw new Error('请求地址不能为空')
    if(Object.prototype.toString.call(obj.url) != '[object String]') throw new Error('请求地址错误')
    if(obj.method === undefined) obj.method = 'get'
    if(obj.method.toLowerCase() != 'get' && obj.method.toLowerCase() != 'post') throw new Error('请求方式只能是get或post')
    if(obj.isAsync === undefined) obj.isAsync = true
    if(Object.prototype.toString.call(obj.isAsync) != '[object Boolean]') throw new Error('isAsync必须是布尔值')
    if(!obj.data) obj.data = null
    if(obj.success === undefined) obj.success = function(){}
    if(Object.prototype.toString.call(obj.success) != '[object Function]') throw new Error('success必须是函数')
    if(obj.error === undefined) obj.error = function(){}
    if(Object.prototype.toString.call(obj.error) != '[object Function]') throw new Error('error必须是函数')
    var data = ''
    if(obj.data != undefined){
        if(Object.prototype.toString.call(obj.data) === '[object String]'){
            if(!obj.data.includes('=')) throw new Error('data数据是非法的！')
            data = obj.data
        }else if(Object.prototype.toString.call(obj.data) === '[object Object]'){
            var arr = []
            for(var key in obj.data){
                arr.push(key + '=' + obj.data[key])
            }
            data = arr.join('&')
        }else throw new Error('data必须是字符串或对象')
        if(obj.method.toLowerCase() === 'get') obj.url += '?' + data
    }
    if(obj.dataType === undefined) obj.dataType = 'json'
    if(obj.dataType.toLowerCase() != 'json' && obj.dataType.toLowerCase() != 'xml' && obj.dataType.toLowerCase() != 'text') throw new Error('dataType只接受json、text、xml')
    var xhr = new XMLHttpRequest;
    xhr.onreadystatechange = function(){
        if(xhr.readyState === 4){
            if(xhr.status>=200 && xhr.status<300){
                var res = '';
                switch(obj.dataType.toLowerCase()){
                    case 'json':
                        res = xhr.responseText
                        res = JSON.parse(res)
                    break;
                    case 'xml':
                        res = xhr.responseXML
                    break;
                    case 'text':
                        res = xhr.responseText
                    break;
                }
                obj.success(res)
            }else obj.error()
        }
    }
    xhr.open(obj.method, obj.url, obj.isAsync);
    if(obj.method.toLowerCase() === 'post' && data){
        xhr.setRequestHeader('content-type', 'application/x-www-form-urlencoded')
        xhr.send(data)
        return
    }
    xhr.send()
}
/////////////////// 调用模板 //////////////////
/*
ajax({
    url: '', // 请求地址 - 必填项
    method: '', // 请求方式 - 可选项，默认get
    data: '', // 请求主体 - 可选项 - 允许字符串/object
    isAsync: true, // 是否异步 - 可选项 - 默认true
    dataType: 'json', // 希望返回的数据格式 - 可选项 - 默认json - 允许json/xml/text
    success: res => {}, // 请求成功后要执行的函数 - 可选项 - 默认是一个匿名函数 - 会将请求回来的数据放在函数中作为参数
    error: function(){} // 请求失败会执行的函数 - 可选项 - 默认是一个匿名函数
})
*/
/**
 * 发送ajax请求的函数
 * @param {object} obj 发送ajax的配置项
 * @returns undefined
 */
function ajaxPromise(obj){
    return new Promise(function(resolve, reject){
        if(obj.url === undefined) throw new Error('请求地址不能为空')
        if(Object.prototype.toString.call(obj.url) != '[object String]') throw new Error('请求地址错误')
        if(obj.method === undefined) obj.method = 'get'
        if(obj.method.toLowerCase() != 'get' && obj.method.toLowerCase() != 'post') throw new Error('请求方式只能是get或post')
        if(obj.isAsync === undefined) obj.isAsync = true
        if(Object.prototype.toString.call(obj.isAsync) != '[object Boolean]') throw new Error('isAsync必须是布尔值')
        if(!obj.data) obj.data = null
        var data = ''
        if(obj.data != undefined){
            if(Object.prototype.toString.call(obj.data) === '[object String]'){
                if(!obj.data.includes('=')) throw new Error('data数据是非法的！')
                data = obj.data
            }else if(Object.prototype.toString.call(obj.data) === '[object Object]'){
                var arr = []
                for(var key in obj.data){
                    arr.push(key + '=' + obj.data[key])
                }
                data = arr.join('&')
            }else throw new Error('data必须是字符串或对象')
            if(obj.method.toLowerCase() === 'get') obj.url += '?' + data
        }
        if(obj.dataType === undefined) obj.dataType = 'json'
        if(obj.dataType.toLowerCase() != 'json' && obj.dataType.toLowerCase() != 'xml' && obj.dataType.toLowerCase() != 'text') throw new Error('dataType只接受json、text、xml')
        var xhr = new XMLHttpRequest;
        xhr.onreadystatechange = function(){
            if(xhr.readyState === 4){
                if(xhr.status>=200 && xhr.status<300){
                    var res = '';
                    switch(obj.dataType.toLowerCase()){
                        case 'json':
                            res = xhr.responseText
                            res = JSON.parse(res)
                        break;
                        case 'xml':
                            res = xhr.responseXML
                        break;
                        case 'text':
                            res = xhr.responseText
                        break;
                    }
                    resolve(res)
                }else reject()
            }
        }
        xhr.open(obj.method, obj.url, obj.isAsync);
        if(obj.method.toLowerCase() === 'post' && data){
            xhr.setRequestHeader('content-type', 'application/x-www-form-urlencoded')
            xhr.send(data)
            return
        }
        xhr.send()
    })
}
/////////////////// 调用模板 //////////////////
/*
ajaxPromise({
    url: '', // 请求地址 - 必填项
    method: '', // 请求方式 - 可选项，默认get
    data: '', // 请求主体 - 可选项 - 允许字符串/object
    isAsync: true, // 是否异步 - 可选项 - 默认true
    dataType: 'json', // 希望返回的数据格式 - 可选项 - 默认json - 允许json/xml/text
})
*/